package com.ssy.lingxi.common.controller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.constant.basic.UserLoginSourceEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.component.redis.service.IRedisUtils;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 公共入口类
 * @author jw.chen
 * @version 2.0.0
 * @date 2020/8/1
 */
public class BaseController {
    @Resource
    private IRedisUtils redisUtils;

    @Resource
    HttpServletRequest request;

    //对象映射工具
    protected ModelMapper modelMapper = new ModelMapper();

    public BaseController() {
        modelMapper.getConfiguration().setAmbiguityIgnored(true);
        //将匹配策略设置为严格策略
        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
    }

    /**
     * 判断用户是否已登录
     * @return 登录-true，未登录-false
     */
    public Boolean isLogin() {
        String token = request.getHeader(Constants.TOKEN);
        if (StringUtils.hasLength(token)) {
            Object obj = redisUtils.get(token, Constants.REDIS_USER_INDEX);
            return obj != null;
        }
        return false;
    }

    /**
     * 判断用户是否已登录，如未登录抛出异常，由各个服务的异常拦截器进行处理
     */
    public void checkLogin(HttpServletRequest request) {
        String token = request.getHeader(Constants.TOKEN);
        if(!StringUtils.hasLength(token) || Objects.isNull(redisUtils.get(token, Constants.REDIS_USER_INDEX))) {
            throw new BusinessException(ResponseCode.TOKEN_DOES_NOT_EXIST_IN_CACHE);
        }
    }

    /**
     * 获取登录用户信息
     * @param request HttpServlet请求
     * @return Redis缓存中的登录用户信息
     */
    public UserLoginCacheDTO getSysUser(HttpServletRequest request) {
        String token = request.getHeader(Constants.TOKEN);
        if (StringUtils.hasLength(token)) {
            Object obj = redisUtils.get(token, Constants.REDIS_USER_INDEX);
            if (obj != null) {
                return JSONUtil.parse(obj).toBean(UserLoginCacheDTO.class);
            } else {
                throw new BusinessException(ResponseCode.TOKEN_DOES_NOT_EXIST_IN_CACHE);
            }
        } else {
            throw new BusinessException(ResponseCode.TOKEN_DOES_NOT_EXIST_IN_CACHE);
        }
    }

    /**
     * 获取平台登录用户信息
     * @param request HttpServlet请求
     * @return Redis缓存中的登录用户信息
     */
    public UserLoginCacheDTO getPlatformUser(HttpServletRequest request) {
        UserLoginCacheDTO user = getSysUser(request);
        if(!UserLoginSourceEnum.BUSINESS_MANAGEMENT_PLATFORM.getCode().equals(user.getLoginSource())){
            throw new BusinessException(ResponseCode.UNAUTHORIZED_REQUEST);
        }
        return user;
    }

    /**
     * 获取登录用户信息
     * @return Redis缓存中的登录用户信息
     */
    public UserLoginCacheDTO getSysUser() {
        String token = request.getHeader(Constants.TOKEN);
        if (StringUtils.hasLength(token)) {
            Object obj = redisUtils.get(token, Constants.REDIS_USER_INDEX);
            if (obj != null) {
                return JSONUtil.parse(obj).toBean(UserLoginCacheDTO.class);
            } else {
                throw new BusinessException(ResponseCode.TOKEN_DOES_NOT_EXIST_IN_CACHE);
            }
        } else {
            throw new BusinessException(ResponseCode.TOKEN_DOES_NOT_EXIST_IN_CACHE);
        }
    }

    /**
     * 获取平台登录用户信息
     * @return Redis缓存中的登录用户信息
     */
    public UserLoginCacheDTO getPlatformUser() {
        UserLoginCacheDTO user = getSysUser(request);
        if(!UserLoginSourceEnum.BUSINESS_MANAGEMENT_PLATFORM.getCode().equals(user.getLoginSource())){
            throw new BusinessException(ResponseCode.UNAUTHORIZED_REQUEST);
        }
        return user;
    }

    /**
     * 获取请求体信息
     * <p>注: 不能与@RequestBody同时使用,流不能重复读取</p>
     * @param request HttpServlet请求
     * @return 请求参数的Json字符串
     */
    protected String getRequestBody(HttpServletRequest request) {
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = request.getReader();
            return IoUtil.read(bufferedReader);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取请求头信息
     * @param request HttpServlet请求
     * @return Map<String, String>对象
     */
    protected Map<String, String> getHeadersInfo(HttpServletRequest request) {
        Map<String, String> map = new HashMap<>();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            String value = request.getHeader(key);
            map.put(key, value);
        }

        return map;
    }

    /**
     * 获取请求头的商城ID
     */
    public Long getHeadersShopId() {
        String shopId = request.getHeader("shopId");
        if(!StringUtils.hasLength(shopId)) {
            throw new BusinessException(ResponseCode.PLATFORM_MANAGE_HEADER_SHOP_ID_CAN_NOT_BE_EMPTY);
        }
        return Long.valueOf(shopId);
    }

    /**
     * 获取请求头的站点ID
     */
    public Long getHeadersSiteId() {
        String siteId = request.getHeader("site");
        if(!StringUtils.hasLength(siteId)) {
            siteId = request.getHeader("siteId");
            if(!StringUtils.hasLength(siteId)) {
                throw new BusinessException(ResponseCode.PLATFORM_MANAGE_HEADER_SITE_ID_CAN_NOT_BE_EMPTY);
            }
        }
        return Long.valueOf(siteId);
    }
}
